/* ** por compatibilidad se omiten tildes **
================================================================================
 TRABAJO PRACTICO 3 - System Programming - ORGANIZACION DE COMPUTADOR II - FCEN
================================================================================
*/

#include "game.h"
#include "tss.h"
#include "sched.h"

char tipo_zombies[3] = {'G','M','C'};
int posicionesA[16];
int posicionesB[16];
unsigned int puntajeA = 0;
unsigned int puntajeB = 0;
char tiposA[8];
char tiposB[8];
char zombisAvivos[CANT_ZOMBIS] = {0,0,0,0,0,0,0,0};
char zombisBvivos[CANT_ZOMBIS] = {0,0,0,0,0,0,0,0};
char j_actual = 'N';
int maxA = 20;
int maxB = 20;

void init_jugadores(){
	tipoA = 0;
	tipoB = 0;
	posA = 1;
	posB = 1;
	ca (*p)[VIDEO_COLS] = (ca (*)[VIDEO_COLS]) VIDEO;
	p[posA][0].c = tipo_zombies[tipoA];
	p[posA][0].a = C_FG_WHITE + C_BG_RED;
	p[posB][79].c = tipo_zombies[tipoB];
	p[posB][79].a = C_FG_WHITE + C_BG_BLUE;
	indice_A = -1;
	indice_B = -1;
}

void game_jugador_mover(unsigned int jugador, unsigned int value) {
	ca (*p)[VIDEO_COLS] = (ca (*)[VIDEO_COLS]) VIDEO;
	switch(jugador){
		case 'A':
			p[posA][0].c = 0;
			p[posA][0].a = C_BG_RED;
			posA += value;
			if (posA == 0){
				posA = 44;
			}
			if(posA	== 45){
				posA = 1;
			}
			p[posA][0].c = tipo_zombies[tipoA];
			p[posA][0].a = C_FG_WHITE + C_BG_RED;
			break;
		default:
			p[posB][79].c = 0;
			p[posB][79].a = C_BG_BLUE;
			posB += value;
			if (posB == 0){
				posB = 44;
			}
			if(posB	== 45){
				posB = 1;
			}
			p[posB][79].c = tipo_zombies[tipoB];
			p[posB][79].a = C_FG_WHITE + C_BG_BLUE;
			break;
	}
}

void game_zombie_rotar(unsigned char jugador, unsigned int value){
	ca (*p)[VIDEO_COLS] = (ca (*)[VIDEO_COLS]) VIDEO;
	if (jugador=='A'){
		tipoA+=value;
		if(tipoA==-1)
			tipoA = 2;
		else
			tipoA = tipoA%3;
		p[posA][0].c = tipo_zombies[tipoA];
	}
	else{
		tipoB+=value;
		if(tipoB == -1)
			tipoB = 2;
		else
			tipoB = tipoB%3;
		p[posB][79].c = tipo_zombies[tipoB];
	}
}

void game_lanzar_zombi(char jugador){
	int indice;
	if(jugador == 'A'){
		if (vivosA() != 8 && maxA > 0){
			maxA--;
			print_hex(maxA,2,47,30,C_FG_WHITE);
			for(indice = 0; zombisAvivos[indice] != 0; indice++);
			completar_tss_zombie(&tss_zombisA[indice],tipo_zombies[tipoA],'A',posA,indice);
			posicionesA[2*indice] = posA;
			posicionesA[(2*indice)+1] = 2;
			zombisAvivos[indice] = 1;
			tiposA[indice] = tipo_zombies[tipoA];
			if (indice_A == -1){
				indice_A = indice;
			}
			if(j_actual == 'N'){
				j_actual = jugador;
			}
		}
	}
	else{
		if (vivosB() != 8 && maxB >0){
			maxB--;
			print_hex(maxB,2,47,48,C_FG_WHITE);
			for(indice = 0; indice < 8 && zombisBvivos[indice] != 0; indice++);
			completar_tss_zombie(&tss_zombisB[indice],tipo_zombies[tipoB],'B',posB,indice);
			posicionesB[2*indice] = posB;
			posicionesB[2*indice+1] = 77;
			zombisBvivos[indice] = 1;
			tiposB[indice] = tipo_zombies[tipoB];
			if (indice_B == -1){
				indice_B = indice;
			}
			if(j_actual == 'N'){
				j_actual = jugador;
			}
		}
	}
}

void game_move_current_zombi(direccion dir){
	ca (*p)[VIDEO_COLS] = (ca (*)[VIDEO_COLS]) VIDEO;
	int x,y,x_ant,y_ant;
	if(j_actual == 'A'){
		x = posicionesA[2*indice_A];
		y = posicionesA[2*indice_A+1];
		x_ant = x;
		y_ant = y;
		p[x][y].c = 'X';
		p[x][y].a = C_BG_GREEN + C_FG_LIGHT_GREY;
		switch(dir){
			case IZQ:
				if (x == 1){
					x = 44;
				}
				else{
					x--;
				}
				break;
			case DER:
				if (x == 44){
					x = 1;
				}
				else{
					x++;
				}
				break;
			case ADE:
				y = y+1;
				if (y==78){
					puntajeA++;
					print_hex(puntajeA,2,47,36,C_FG_WHITE);
				}
				break;
			case ATR:
				y = y-1;
				if (y==1){
					puntajeB++;
					print_hex(puntajeB,2,47,42,C_FG_WHITE);
				}
				break;
			default:
				desalojar_tarea();
				break;
		}
		posicionesA[2*indice_A] = x;
		posicionesA[2*indice_A+1] = y;
		if (y!=1 && y!=78){
			void* ubic = ubicacion(x,y);
			void* ubic_ant = ubicacion(x_ant,y_ant);
			mmu_mapear_cuadrado(x,y,tss_zombisA[indice_A].cr3,'A');
			mmu_mapear_pagina((unsigned int)ubic_ant,rcr3(),(unsigned int)ubic_ant,0);
			mmu_mapear_pagina((unsigned int)ubic,rcr3(),(unsigned int)ubic,0);
			cpy_code((char*)ubic,ubic_ant,0x1000);
			mmu_unmapear_pagina((unsigned int)ubic_ant,rcr3());
			mmu_unmapear_pagina((unsigned int)ubic,rcr3());
			p[x][y].c = tiposA[indice_A];
			p[x][y].a = C_BG_RED;
		}
		else{
			p[x][y].c = 'X';
			p[x][y].a = C_BG_GREEN + C_FG_RED;
			desalojar_tarea();
		}
		
	}
	else{
		x = posicionesB[2*indice_B];
		y = posicionesB[2*indice_B+1];
		x_ant = x;
		y_ant = y;
		p[x][y].c = 'X';
		p[x][y].a = C_BG_GREEN + C_FG_LIGHT_GREY;
		switch(dir){
			case IZQ:
				if (x == 44){
					x = 1;
				}
				else{
					x++;
				}
				break;
			case DER:
				if (x == 1){
					x = 44;
				}
				else{
					x--;
				}
				break;
			case ADE:
				y = y-1;
				if (y==1){
					puntajeB++;
					print_hex(puntajeB,2,47,42,C_FG_WHITE);
				}
				break;
			case ATR:
				y = y+1;
				if (y==78){
					puntajeA++;
					print_hex(puntajeA,2,47,36,C_FG_WHITE);
				}
				break;
			default:
				desalojar_tarea();
				break;
		}
		posicionesB[2*indice_B] = x;
		posicionesB[2*indice_B+1] = y;
		if (y!=1 && y!=78){
			void* ubic = ubicacion(x,y);
			void* ubic_ant = ubicacion(x_ant,y_ant);
			mmu_mapear_cuadrado(x,y,tss_zombisB[indice_B].cr3,'B');
			mmu_mapear_pagina((unsigned int)ubic_ant,rcr3(),(unsigned int)ubic_ant,0);
			mmu_mapear_pagina((unsigned int)ubic,rcr3(),(unsigned int)ubic,0);
			cpy_code((char*)ubic,(char*)ubic_ant,0x1000);
			mmu_unmapear_pagina((unsigned int)ubic_ant,rcr3());
			mmu_unmapear_pagina((unsigned int)ubic,rcr3());
			p[x][y].c = tiposB[indice_B];
			p[x][y].a = C_BG_BLUE;
		}
		else{
			p[x][y].c = 'X';
			p[x][y].a = C_BG_GREEN + C_FG_RED;
			desalojar_tarea();
		}
	}
}

void desalojar_tarea(){
	if (j_actual=='A'){
		zombisAvivos[indice_A] = 0;
		if(vivosA() == 0 && vivosB() == 0){
			j_actual = 'N';			
		}
	}
	else{
		zombisBvivos[indice_B] = 0;
		if (vivosA() == 0 && vivosB() == 0){
			j_actual = 'N';
		}
	}
}